

#ifndef _PG_WORLDAIINTERFACE_H
#define _PG_WORLDAIINTERFACE_H

#include "Common.h"
#include "Resource.h"
#include "Threading/Mutex.h"
#include "ScriptMgr.h"
#include "Game.h"
#include "XMLData.h"
#include "Threading/AtomicCounter.h"
#include "AIInterface.h"
#include "PGPubStruct.h"

#ifdef M_PI
#undef M_PI
#endif


 
#define M_PI	   3.14159265358979323846
#define UNIT_MOVEMENT_INTERPOLATE_INTERVAL 400/*750*/ // ms smoother server/client side moving vs less cpu/ less b/w
#define TARGET_UPDATE_INTERVAL_ON_PLAYER 1000 // we most likely will have to kill players and only then check mobs
// 增删玩家对象锁
#define WGS_DELETECHAR_INNER_MUTEX_NAME g_deletechar_inner_mutex
#define WGS_DELETECHAR_INNER_LOCK		boost::lock_guard<boost::mutex> wgsDeleteCharInnerMutexLock(WGS_DELETECHAR_INNER_MUTEX_NAME);
extern  boost::mutex WGS_DELETECHAR_INNER_MUTEX_NAME;

class CharPtr;
class ChannelPtr;
class WorldPacket;
struct stJBPHistory;
struct WSSocketPtr;
struct VIPCard;
struct small_game_st;
typedef small_game_st SMGameData;

namespace AIScript 
{

#define TO_TOWN_INTERFACE(ptr) dynamic_cast<PGTownInterface *>(ptr)
#define TO_CREATURE_INTERFACE(ptr) dynamic_cast<PGCreatureInterface *>(ptr)
#define TO_CHANNEL_INTERFACE(ptr) dynamic_cast<PGChannelInterface *>(ptr)
#define TO_PGTOWN_INTERFACE(ptr) dynamic_cast<PGTownInterface *>(ptr)
#ifdef TO_EFFECT_INTERFACE
#endif

class SERVER_DECL PGTownInterface : public AIInterface
{
// 牌桌列表锁
#define WGS_TW_CHNLIST_INNER_MUTEX_NAME town_chnnel_list_inner_mutex 
#define WGS_TW_CHNLIST_INNER_MUTEX mutable boost::mutex WGS_TW_CHNLIST_INNER_MUTEX_NAME; //定义锁
#define WGS_TW_CHNLIST_INNER_LOCK boost::lock_guard<boost::mutex> wgsTownChnListInnerMutexLock(WGS_TW_CHNLIST_INNER_MUTEX_NAME);/*lock_guard 自解锁，与mutex配合使用，把锁放进lock_guard中时，
																																mutex自动上锁，lock_guard析构时，同时mutex解锁；在函数体积较长切存在多分支时使用*/
WGS_TW_CHNLIST_INNER_MUTEX
// 加入牌桌逻辑锁
#define WGS_TW_JOINCHN_INNER_MUTEX_NAME town_join_chnnel_inner_mutex
#define WGS_TW_JOINCHN_INNER_MUTEX mutable boost::mutex WGS_TW_JOINCHN_INNER_MUTEX_NAME;
#define WGS_TW_JOINCHN_INNER_LOCK		boost::lock_guard<boost::mutex> wgsTownJoinChnInnerMutexLock(WGS_TW_JOINCHN_INNER_MUTEX_NAME);
WGS_TW_JOINCHN_INNER_MUTEX
	public:
		ADD_INTERFACE_FACTORY_FUNCTION(PGTownInterface)
		PGTownInterface(Resource * town);
		~PGTownInterface(void);
		void Load(void);
		void Update(const uint32 & p_time);	
	public:
		// 获取牌桌列表
		void GetTableList(std::list<ChannelPtr> &lstChannel);
		// 进入一个牌桌
		uint8 JoinOneChannel(CharPtr & pChr, const uint32 chnId = 0);
		// 离开房间
		uint8 LeaveChannel(CharPtr & pChr, bool bOffline = false);
		bool JoinRoom(CharPtr &pChr);
		// 检测是否可以加入该房间，返回结果
		uint32 CheckCondition(CharPtr &pChr, bool bFirst = true);
		// 更新玩家数量
		void UpdatePlayerNumber(bool bAdd = true); 
		// 广播房间所有人
		void Broadcast(WorldPacket *pPacket);
	private:
		// 获取指定牌桌
		ChannelPtr GetChannelPtr(const uint32 channelId, uint32 &tableIndex);
		ChannelPtr GetChannelPtr(const uint32 channelId);
		// 获取分配优先级最高的牌桌
		ChannelPtr GetBestChannelPtr(uint32 &tableIndex);
		// 创建新的牌桌
		ChannelPtr CreateNewChannel();
	private:	
		// 牌桌列表
		std::list<ChannelPtr> m_lstChannels;
		// 当前人数
		Threading::AtomicCounter m_curNumber;
		// 牌桌检测时间
		uint32 lastCheckTime;
	};
	
	/* 世界角色接口类 */
	class SERVER_DECL PGCreatureInterface : public AICreatureBaseInterface
	{
	// 玩家下注锁
	#define WGS_CHR_CHIPS_INNER_MUTEX_NAME chr_chip_inner_mutex
	#define WGS_CHR_CHIPS_INNER_MUTEX mutable boost::mutex WGS_CHR_CHIPS_INNER_MUTEX_NAME;
	#define WGS_CHR_CHIPS_INNER_LOCK boost::lock_guard<boost::mutex> wgsChrChipInnerMutexLock(WGS_CHR_CHIPS_INNER_MUTEX_NAME);
		WGS_CHR_CHIPS_INNER_MUTEX


	  public:
		ADD_INTERFACE_FACTORY_FUNCTION(PGCreatureInterface);
		PGCreatureInterface(Resource * pUnit);
		~PGCreatureInterface();
	
		void Load(void);
		void Update(const uint32 & p_time);
	public:
		// 设置房间ID,牌桌ID
		WGSERVER_INLINE void SetTownAndChannelId(const uint32 townId = 0, const uint32 chnId = 0) 
		{
			m_iTownId = townId; 
			m_iChannelId = chnId; 
			m_channel = ResourceProxy(m_iChannelId, ResourceTypeChannel);
		}
		// 设置和获取
		WGSERVER_INLINE uint32 GetTownId() const {return m_iTownId;}
		WGSERVER_INLINE uint32 GetChannelId() const {return m_iChannelId;}
	
		/************下注相关**********/
		// 计算下注金额，返回对局费差额
		const uint32 ComputeRealChip(const uint32 pos, const uint32 chip);
		// 下注
		bool AddChips(const uint32 pos, const uint32 chips, String fieldName);
		// 获取当前下注筹码
		const uint32 GetCurChipsIn();
		// 获取某门的下注筹码
		const uint32 GetChip(const uint32 pos);
		// 获取对局费
		const uint32 GetJoinCost();
		// 获取冻结金额
		const uint32 GetFrozenCapital();
		/*********************************/
		// 领取礼包，返回领取结果
		uint32 GetGifts(const uint32 giftType);
		// 添加新成就
		bool AddNewTitle(const uint32 titleId);
		// 设置和获取上次登录时间
		WGSERVER_INLINE void SetLastLoginTime(int32 lastTime){m_lastLoginTime = lastTime;}
		WGSERVER_INLINE int32 GetLastLoginTime(){return m_lastLoginTime;}
		void ComputeNextOnlineGift();
	private:
		// 更新经验
		void UpdateExps(ResourceEvent * event);
		// 重置每日输赢数据
		void ResetLossWinPerDay(const uint32 curTime, const bool bCancelLock = false);
		// 7.26补偿数据
		void Compensate();
	private:
		// 房间ID
		uint32 m_iTownId;
		// 牌桌ID
		uint32 m_iChannelId;
		// 上次登录时间
		uint32 m_lastLoginTime;
	};
	// 战场状态
	enum ChannelStatus
	{
		en_ChannelStatus_Idle = 100, // 空闲
		en_ChannelStatus_Run,	// 活动
		en_ChannelStatus_WaitDelete, // 等待删除
	};
	/* 世界战场接口类 */
	class SERVER_DECL PGChannelInterface : public AIChannelBaseInterface
	{
	// 庄家锁
	#define WGS_BANKER_INNER_MUTEX_NAME banker_inner_mutex
	#define WGS_BANKER_INNER_MUTEX mutable boost::mutex WGS_BANKER_INNER_MUTEX_NAME;										  // 定义互斥锁
	#define WGS_BANKER_INNER_LOCK boost::lock_guard<boost::mutex> wgsChrChannelInnerMutexLock(WGS_BANKER_INNER_MUTEX_NAME);	  /*std::lock_guard是一个局部变量,lock_guard是与mutex配合使用, \ \
																																 把锁放到lock_guard中时，mutex自动上锁，lock_guard析构时，同时把mutex解锁。*/
		WGS_BANKER_INNER_MUTEX

	//牌局流程锁
	#define WGS_CHANNEL_MUTEX_NAME chn_change_mutex
	#define WGS_CHANNEL_MUTEX mutable boost::mutex WGS_CHANNEL_MUTEX_NAME;
	#define WGS_CHANNEL_LOCK boost::lock_guard<boost::mutex> wgsChnChangeMutexLock(WGS_CHANNEL_MUTEX_NAME);
		WGS_CHANNEL_MUTEX
		
	  public:
		// 牌桌状态
		enum ChannelState
		{
			en_ChannelState_Prepare = 1,	   // 准备
			en_ChannelState_RobBanker = 2,	 // 抢庄定庄
			en_ChannleState_Shuffle = 3,	   // 洗牌
			en_ChannelState_CutThrowDice = 4,  // 丢骰子决定切牌位置
			en_ChannelState_Cut = 5,		   // 切牌
			en_ChannelState_ChipIn = 6,		   // 下注
			en_ChannelState_DealThrowDice = 7, // 丢骰子决定发牌位置
			en_ChannelState_Deal = 8,		   // 发牌
			en_ChannelState_Move = 9,		   // 摆牌
			en_ChannelState_LookCards = 10,	// 看牌
			en_ChannelState_CalcWait = 11,	 // 结束
			en_ChannelState_GameOver = 12,
			en_ChannelState_ShowTime = 13, // 播放动画等待时间

		};

		// 玩家抢庄操作
		enum LootBanker
		{
			en_LootBanker_Init = 255, // 默认
			en_LootBanker_No = 0,	 // 不抢
			en_LootBanker_Yes = 1,	// 抢
		};
		// 玩家切牌操作
		enum CutCards
		{
			en_CutCards_Init = 255, // 默认
			en_CutCards_No = 0,		// 不切
			en_CutCards_Yes = 1,	// 切
		};

		//游戏模式
		enum GameMmode
		{
			en_GameMode_RobBanker = 1,		//抢庄模式
			en_GameMode_OverLordBanker = 2, //霸王庄模式
			en_GameMode_Orderbanker = 3,	//轮庄模式

		};
		// 庄家应答
		enum AnswerType
		{
			en_AnswerType_Yes = 1, // 切锅（让庄）
			en_AnswerType_No = 2,  // 不切锅（连庄）
		};
		// 下庄原因
		enum AbandonStatus
		{
			en_AbandonStatus_NoMoney = 1,  //庄家输完
			en_AbandonStatus_Multiple = 2, //到达切锅倍数
			en_AbandonStatus_Active = 3,   //主动让庄
		};
		// 结果类型
		enum ResultType
		{
			en_ResultType_Normal = 1,	// 普通
			en_ResultType_FullWin = 2,   // 通杀
			en_ResultType_FullFaild = 3, // 通赔
		};
		enum enSetBankerMode
		{
			enSetBanker_Normal = 0,			   //抢庄
			enSetBanker_Random = 1,			   //庄
			enSetBanker_Combo = 2,			   //连庄
			enSetBanker_QiangRandomBanker = 6, //抢庄人随机庄
		};

		// 玩家游戏状态
		enum PlayStatus
		{
			en_PlayStatus_Idle = 1,	// 空闲
			en_PlayStatus_Ready = 2,   // 准备
			en_PlayStatus_Start = 3,   // 开始
			en_PlayStatus_Extra = 4,   // 附加
			en_PlayStatus_OffLine = 5, // 离线
		};

	  public:
		ADD_INTERFACE_FACTORY_FUNCTION(PGChannelInterface);
		PGChannelInterface(Resource *channel);
		~PGChannelInterface(void);
		void Load();
		void Update(const uint32 &p_time);

	  public:
		void initialize(void);
		uint32 GetMaxPlayerNum();
		const char *GetPlayerName(TablePlayer player);									   // 获得开桌的最大玩家数量
																						   // 加入牌桌, 返回是否新加入该牌桌
		virtual bool JoinChannel(CharPtr &pChr, bool bSendJoinTown = true);				   //进入战场
		virtual void ReturnRoom(TablePlayer *pTp);										   //玩家返回战场
		virtual bool ExitChannel(CharPtr &pChr, bool bOffline = false, bool bLock = true); //退出战场
		// 庄家应答
		void BankerAnswer(CharPtr &pChr, const uint32 answer);
		// 获取已出的牌
		inline std::vector<TablePlayer> &GetOutCardsList() { return m_lstOutCards; } /*内联函数，关键字必须与函数定义在一块，inline 定义的类的内联函数，
																				函数的代码被放入符号表中，在使用时直接进行替换，（像宏一样展开），没有了调用的开销，效率也很高*/
		// 获取当前状态
		uint32 GetCurrentState() const { return m_curState; }
		// 投注
		uint32 AddChips(CharPtr &pChr, const uint32 &num, const uint32 &score, bool bLock);
		// 丢骰子
		void ThrowDice(CharPtr &pChr, const uint32 dice, const uint32 pos);
		// 方位列表
		std::vector<TablePlayer> &GetPositionInfo() { return PlayerPos; }
		// 广播座位上玩家下注 by starx 2018-2-5
		void BroadcastSeatChip(CharPtr &pChr, const uint32 &num, const uint32 &score, bool bLock);
		//初始化棋牌圈
		void InitCenterBattleInto(void);
		//玩家看牌请求
		void PlayerLookCard(CharPtr &pChr);
		//获取玩家座位号
		uint8 PlayerSeatNumber(CharPtr &pChr);
		std::map<uint32, uint32> GetNumChips(CharPtr &pChr);
		//玩家摆牌
		void PlayermoveCard(CharPtr &pChr, const uint8 index1, const uint8 index2);
		//玩家摆牌最终结果
		void PlayerMoveCardFinish(CharPtr &pChr);
		//玩家获取提示牌型
		void PlayerPromptCardsType(CharPtr &pChr);
		//检测自己两两组合牌型
		Cards SelfCardsTypeCheck(Cards card1, const uint8 index1, const uint8 index2, uint8 &result, bool Isnew = true);
		//系统处理满足条件的牌型组合
		Cards SystemProcessCardsType(TablePlayer tp);
		//返回符合条件的最大牌型组合
		Cards MaximumCardTypeCombination(std::vector<Cards> CardsType,const uint8 &opt = 0);
		//获取切牌玩家列表
		void PlayerCutCards(CharPtr &pChr, const uint8 result);
		//当前玩家切牌位置索引
		void PlayerCutCardsPos(CharPtr &pChr, const uint32 cutcardpos);
		//玩家完成切牌标志
		void PlayerCutCardsFinsh(CharPtr &pChr);
		//玩家准备或退出
		bool PlayerReadyOrBack(CharPtr &pChr);
		//小结算确认
		void AskIsRoundPGCalc(CharPtr &pChr, const uint8 & ask);
		// 产生庄家位置
		void SetBankerPos();
		// 抢庄
		bool LootBanker(CharPtr &pChr, const uint8 &op_mode);
		//计算输赢分
		uint32 EveryScore(std::map<uint32, uint32> tp, const uint32 &Num);
		//积分以及赛果计算
		void CalcScoreResult();
		//游戏数据记录
		void CalcGameResultLog();
		//不够赔的算分逻辑
		TablePlayer Analysis(TablePlayer max, std::vector<TablePlayer> WinPlayer, const uint8 &i);
		void Analysis(TablePlayer max, TablePlayer center, std::vector<TablePlayer> WinPlayer, const uint8 &i);
		void Analysis(std::vector<TablePlayer> WinPlayer, const uint8 &num = 0);

		void SendCenterBattleInfo(const uint8 & baseScore);
		//获取最先发牌玩家
		TablePlayer FindBefore(std::vector<TablePlayer> Free, const uint8 &num);
		//找到最大牌型玩家
		TablePlayer FindMax(std::vector<TablePlayer> CardsType, const uint8 &num, const uint8 opt);
		//获取真实座位号
		uint8 FindRealPos(TablePlayer Ps);
		//相同牌型玩家数量
		uint8 SameNum(const uint8 &res1, const uint8 &res2, const uint8 &res3);

		void Ready(CharPtr &pChr);
		//检查玩家人数是否满足开始游戏条件
		bool CheckPlayersCanStatPlayGame();
		//同意或拒绝进行游戏
		bool AgreeOrRefusePlayGame(CharPtr &pChr, const uint8 &agree);
		bool CheckGameStart();
		bool PlayerStandUp(CharPtr &pChr);
		//计算成为过庄家的人数
		bool AllInTurn();
		bool CurNum(CharPtr &pChr,const uint32 curnum);
		bool BroadLookOtherPlayerCards(CharPtr &pChr, const uint8 &otherpos);
		//特定牌测试
		void ShuffleText(const size_t &i);
		//广播玩家下注情况
		void BroadPlayerChinResult(CharPtr &pChr, std::map<uint32, uint32> numchips, const uint32 &num, const uint32 &surscore);
		//广播
		void BroadcastPacketBC(WorldPacket *packet, const uint32 &exceptId = 0);
		// 玩家发起投票
		bool PlayerSendVote(CharPtr &pChr);
		// 处理投票
		bool PlayerDealVote(CharPtr &pChr, const uint8 &mode);
		// 房主发起解散牌桌
		bool DissolveChannel();
		// 玩家退出牌桌
		void AllPlayersLeaveRoom();
		// 赠送互动道具
		uint8 GiveFreeGift(CharPtr &pChr, const uint32 &char_id, const uint8 &gift_id);

	  public:
		uint32 m_nChannelPlayerNum; //在牌桌里的人数
		uint32 m_nWarPlayerNum;		//参与游戏的玩家数量
		uint32 m_nBnkerTimes;		//抢庄人数
		uint32 m_nOptTimes;			//操作次数
		uint8 m_nBankerPos;			//庄家座位
		uint8 m_nGetBankerMode;		//定庄模式
		uint32 m_nLoopBankerMode;   //轮庄模式
		bool  m_nOnceSend;			//仅有一次发送
		bool m_bComboBanker;		//庄稼连庄
		bool m_bSetBanker;			//庄稼产生
		bool m_contOrstop;			//是否已操作
		bool m_bCompare;			//游戏结果是否已经产生
		BattleTotalLog m_btLog;		// 组局数据记录
		bool m_bAddCenterBattleLog; // 是否添加组局日志（0 否 1 是）
									//-------------------JSON数据-------------------------
		uint32 m_nFzPid;			// 房主PID
		uint32 m_nBasePoint;		// 底分
		uint32 m_readyTime;			//玩家准备后等待开桌的时间
		uint32 m_nLimitLoop;		// 限制轮次
		uint32 m_nLimitTime;		// 限制时间
		uint32 m_nTopTimes;			// 封顶倍数
		uint32 m_nGameID;			// 游戏ID
		uint32 m_nGzid;				// 游戏分区ID
		uint8 m_nMode;				// 游戏玩法模式
		uint32 m_nLoopId;			// 轮次ID
		uint8 m_IsDjnn;				//地九靓靓
		uint8 m_IsGz;				//鬼子
		uint8 m_IsTWJ;				//天王九
		uint8 m_IsZDY;				//炸弹一
		uint8 m_nNumBar;			//杠数
		uint32 m_nAAPay_ModelId;	// AA付费模式号
		uint32 m_nAAPay_num;		// AA付费数量
		uint32 m_nPaymode;			// 付费模式
									//----------------------------------------------------
		uint32 m_nGameStartTime;	// 游戏开始时间
		uint32 m_nLastSitTime;		// 最后一个坐下的时间（用于让才坐下的玩家开始游戏有一个时间缓存一下）
		uint32 m_status_endtimer;   //当前状态机结束时间

		uint32 m_nVoteOverTime; // 投票结束时间
		uint8 m_nVotePos;		// 发起投票玩家位置
		uint8 m_nDissolveReson; // 牌桌解散原因

		uint8 m_nQiangBankerMode;		  //抢庄模式(0 第一局 1 庄家离开)
		bool m_bGameOver;				  // 游戏结束
		bool m_bPlaying;				  // 正在游戏
		bool m_bFinishCalc;				  // 完成结算
		bool m_bIsAllCalc;
		uint32 m_nMaxPlayerNum;			  // 最大开局人数
		bool m_CardIsEmpty;				  // 当前牌是否发完
		uint32 m_nWaitPlayerStartTimer;   // 等待玩家开始时间
		bool m_bFirstStartGame;			  // 第一次确认开始游戏
		bool m_bInitCenterData;			  // 初始组局数
		String m_strPlayJsonData;		  // 玩法附加数据
		String m_strPlayJsonDataCommon;   // 公共协议需要的json数据
		uint8 m_nCanGetBankerNum;		  //可以进行抢庄的人的数量
		uint32 m_nAAPay_ModelID;		  // AA付费模式号
		uint32 m_nAAPay_Num;			  // AA付费数量
		uint32 m_nPayMode;				  // 付费模式
		int m_BaseScore;				  // 庄家底分剩余
		uint32 m_nQiangZhuangBeiShu;	  // 抢庄倍数
		uint32 m_Gamenumber;			  //游戏进行局数
		TownPtr m_Town;					  //战场所在房间ID
		std::vector<uint8> m_bWantBanker; //抢庄列表(255 默认 0 不抢 1 抢）
		SpecialType m_specialtype;

	  public:
		std::map<uint32, stVotePlayer> m_mapVotePlayers; // 投票玩家状态
	  public:
		// //战场状态相关
		// WGSERVER_INLINE void setRunStatus(const ChannelRunStatus &status) { m_run_status = status; }
		// WGSERVER_INLINE ChannelRunStatus GetRunStatus() { return m_run_status; }

		// //状态结束时间相关
		// WGSERVER_INLINE void setStatusEndTimer(const uint32 &timer) { m_status_endtimer = now() + timer; }
		// WGSERVER_INLINE uint32 getStatusEndTimer() { return m_status_endtimer; }

	  private:
		/****状态机相关*****/
		// 切换状态
		HSMStateHandler ChangeChannelState(ChannelState state);
		// 初始状态
		static HSMState channel_init(PGChannelInterface *me, HSMEvent const *e);
		// 准备状态
		static HSMState channel_prepare(PGChannelInterface *me, HSMEvent const *e);
		void InitPrepareState();
		HSMStateHandler PrepareUpdate();
		// 抢庄定庄状态
		static HSMState channel_Rob_Banker(PGChannelInterface *me, HSMEvent const *e);
		void InitRobBankerState();
		HSMStateHandler RobBankerUpdate();
		// 洗牌状态
		static HSMState channel_shuffle_cards(PGChannelInterface *me, HSMEvent const *e);
		void InitShuffleCardState();
		HSMStateHandler ShuffleCardUpdate();
		// 丢骰子切牌状态
		static HSMState channel_cutthrow_dice(PGChannelInterface *me, HSMEvent const *e);
		void InitCutThrowDiceState();
		HSMStateHandler CutThrowDiceUpdate();
		// 切牌状态
		static HSMState channel_cut_cards(PGChannelInterface *me, HSMEvent const *e);
		void InitCutCardInState();
		HSMStateHandler CutCardInUpdate();
		// 下注状态
		static HSMState channel_chip_in(PGChannelInterface *me, HSMEvent const *e);
		void InitChipInState();
		HSMStateHandler ChipInUpdate();
		// 丢骰子发牌状态
		static HSMState channel_dealthrow_dice(PGChannelInterface *me, HSMEvent const *e);
		void InitDealThrowDiceState();
		HSMStateHandler DealThrowDiceUpdate();
		// 发牌状态
		static HSMState channel_deal_cards(PGChannelInterface *me, HSMEvent const *e);
		void InitDealState();
		HSMStateHandler DealUpdate();
		// 摆牌状态
		static HSMState channel_move_cards(PGChannelInterface *me, HSMEvent const *e);
		void InitMoveCardsState();
		HSMStateHandler MoveCardsUpdate();
		// 看牌状态
		static HSMState channel_look_cards(PGChannelInterface *me, HSMEvent const *e);
		void InitLookCardsState();
		HSMStateHandler LookCardsUpdate();
		//游戏结算状态
		static HSMState channel_calc_wait(PGChannelInterface *me, HSMEvent const *e);
		void InitCalcWaitState();
		HSMStateHandler CalcWaitUpdate();
		//游戏结束状态
		static HSMState channel_game_over(PGChannelInterface *me, HSMEvent const *e);
		void InitGameOverState();
		// 等待动画播放阶段
		static HSMState channel_show_time(PGChannelInterface *me, HSMEvent const *e);
		void InitShowTime();
		HSMStateHandler ShowTimeUpdate();

	  private:
		// 重置数据
		void ResetData();
		// 下发当前牌桌状态
		void SendTableState(WSSocketPtr &socket, const uint32 waitTime = 0);
		// NPC处理逻辑
		void NPCLogic();
		// 获取玩家牌桌信息
		TablePlayer *GetTablePlayer(const uint32 chrId);
		// 更新VIP玩家列表
		void UpdateVIPPlayers(const bool bLock = true);

	  private:
		std::list<ResourceProxy> m_lstChars;	  // 玩家列表
		std::vector<ResourceProxy> m_vecVipChars; // 特权玩家列表
		std::vector<TablePlayer> PlayerPos;
		std::map<uint32, TablePlayer> m_mapFreePlayers; //空闲玩家列表
		std::vector<PaiGowType> m_vecCurCards;			// 当前牌列表
		std::vector<TablePlayer> m_lstOutCards;			// 已出的牌
		TownPtr m_pTown;		  // 房间对象
		uint32 m_curState;		  // 状态
		uint32 m_curWaitOperator; // 当前等待的操作
		uint32 m_beginWaitTime;   // 开始等待时间（ms）
		//uint32 m_nExtraAnimeTimer;						// 动画额外等待时间
		uint32 m_bankerAnswer; // 庄家应答操作
		uint32 m_lastSaveTime; // 记录时间（ms）
		uint32 m_status_waitimer;
		uint32 m_beginShowTime;
		uint32 m_dealStartPos; // 发牌起始位置
		uint32 m_nSpeakPos;	// 当前说话位置
		bool m_bVoting;		   // 投票中
		uint32 m_dices1;	   // 骰子数及位置
		uint32 m_dices2;
		uint32 m_dices;
		uint32 m_cutStartPos;   //首次切牌玩家位置
		uint8 m_chinNum;		//已下注人数
		bool m_changeBanker;	//到达切锅条件
		uint32 m_cutplayer;		//已经选择切牌选项玩家
		ResultType m_rType;		// 牌桌结果类型
		uint32 m_lastCheckTime; // 最后检测时间
		uint32 m_curChipLimit;  // 本轮玩家下注上限
	};
	
	//------------------------------------------------------------------------
	/* 世界区域接口类 */
	class SERVER_DECL PGRegionInterface : public AIInterface
	{
	public:
		ADD_INTERFACE_FACTORY_FUNCTION(PGRegionInterface);
		PGRegionInterface(Resource * pUnit);
		~PGRegionInterface();
		void Load(void);
		void Update(const uint32 & p_time);
		void Spawn(void);
		bool isLoadChildren(void);
	protected:
		uint32 	m_curSpawnCount;
		uint32 	m_spawnLastTimer;
	};
	
	/* 世界SOCKET接口类 */
	class SERVER_DECL PGSocketInterface : public AIInterface
	{
	public:
		ADD_INTERFACE_FACTORY_FUNCTION(PGSocketInterface);
		PGSocketInterface(Resource * pUnit);
		~PGSocketInterface();
		
		void 	Load(void);
		void 	OnActivate(ResourcePtr & pParter);
		void  	Deactivate( ResourcePtr & pParter );

	};
	/* 效果接口类 */
	class SERVER_DECL WAIEffectInterface : public AIInterface
	{
	public:
		ADD_INTERFACE_FACTORY_FUNCTION(WAIEffectInterface);
		WAIEffectInterface(Resource * pUnit);
		~WAIEffectInterface();
		
		void Load(void);
		void Update(const uint32 & p_time);
	};
}
#endif // _PG_WORLDAIINTERFACE_H
